/*
 evol-colorpicker 3.4.2
 ColorPicker widget for jQuery UI
 https://github.com/evoluteur/colorpicker
 (c) 2020 Olivier Giulieri
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 */

(function( $, undefined ) {

    var _idx=0,
        ua=window.navigator.userAgent,
        isIE=ua.indexOf("MSIE ")>0,
        _ie=isIE?'-ie':'',
        isMoz=isIE?false:/mozilla/.test(ua.toLowerCase()) && !/webkit/.test(ua.toLowerCase()),
        history=[],
        baseThemeColors=['ffffff','000000','eeece1','1f497d','4f81bd','c0504d','9bbb59','8064a2','4bacc6','f79646'],
        subThemeColors=['f2f2f2','7f7f7f','ddd9c3','c6d9f0','dbe5f1','f2dcdb','ebf1dd','e5e0ec','dbeef3','fdeada',
            'd8d8d8','595959','c4bd97','8db3e2','b8cce4','e5b9b7','d7e3bc','ccc1d9','b7dde8','fbd5b5',
            'bfbfbf','3f3f3f','938953','548dd4','95b3d7','d99694','c3d69b','b2a2c7','92cddc','fac08f',
            'a5a5a5','262626','494429','17365d','366092','953734','76923c','5f497a','31859b','e36c09',
            '7f7f7f','0c0c0c','1d1b10','0f243e','244061','632423','4f6128','3f3151','205867','974806'],
        standardColors=['c00000','ff0000','ffc000','ffff00','92d050','00b050','00b0f0','0070c0','002060','7030a0'],
        webColors=[
            ['003366','336699','3366cc','003399','000099','0000cc','000066'],
            ['006666','006699','0099cc','0066cc','0033cc','0000ff','3333ff','333399'],
            ['669999','009999','33cccc','00ccff','0099ff','0066ff','3366ff','3333cc','666699'],
            ['339966','00cc99','00ffcc','00ffff','33ccff','3399ff','6699ff','6666ff','6600ff','6600cc'],
            ['339933','00cc66','00ff99','66ffcc','66ffff','66ccff','99ccff','9999ff','9966ff','9933ff','9900ff'],
            ['006600','00cc00','00ff00','66ff99','99ffcc','ccffff','ccccff','cc99ff','cc66ff','cc33ff','cc00ff','9900cc'],
            ['003300','009933','33cc33','66ff66','99ff99','ccffcc','ffffff','ffccff','ff99ff','ff66ff','ff00ff','cc00cc','660066'],
            ['333300','009900','66ff33','99ff66','ccff99','ffffcc','ffcccc','ff99cc','ff66cc','ff33cc','cc0099','993399'],
            ['336600','669900','99ff33','ccff66','ffff99','ffcc99','ff9999','ff6699','ff3399','cc3399','990099'],
            ['666633','99cc00','ccff33','ffff66','ffcc66','ff9966','ff6666','ff0066','d60094','993366'],
            ['a58800','cccc00','ffff00','ffcc00','ff9933','ff6600','ff0033','cc0066','660033'],
            ['996633','cc9900','ff9900','cc6600','ff3300','ff0000','cc0000','990033'],
            ['663300','996600','cc3300','993300','990000','800000','993333']
        ],
        transColor='#0000ffff',
        int2Hex=function(i){
            var h=i.toString(16);
            if(h.length==1){
                h='0'+h;
            }
            return h;
        },
        st2Hex=function(s){
            return int2Hex(Number(s));
        },
        int2Hex3=function(i){
            var h=int2Hex(i);
            return h+h+h;
        },
        toHex3=function(c){
            if(c.length>10){ // IE9
                var p1=1+c.indexOf('('),
                    p2=c.indexOf(')'),
                    cs=c.substring(p1,p2).split(',');
                return ['#',st2Hex(cs[0]),st2Hex(cs[1]),st2Hex(cs[2])].join('');
            }else{
                return c;
            }
        };
    
    $.widget( "evol.colorpicker", {
    
        version: '3.4.0',
        
        options: {
            color: null, // example:'#31859B'
            customTheme: null, // example: ["#ff0000", "#00ff00", "blue"],
            showOn: 'both', // possible values: 'focus','button','both'
            hideButton: false,
            displayIndicator: true,
            transparentColor: false,
            history: true,
            defaultPalette: 'theme', // possible values: 'theme', 'web'
            strings: 'Theme Colors,Standard Colors,Web Colors,Theme Colors,Back to Palette,History,No history yet.'
        },
    
        // this is only true while showing the palette until color is chosen
        _active: false,
    
        _create: function() {
            var that=this;
            var color=this.options.color;
            this._paletteIdx=this.options.defaultPalette=='theme'?1:2;
            this._id='evo-cp'+_idx++;
            this._enabled=true;
            this.options.showOn=this.options.hideButton?'focus':this.options.showOn;
            switch(this.element.get(0).tagName){
                case 'INPUT':
                    var e=this.element,
                        css=((this.options.showOn==='focus')?'':'evo-pointer ')+'evo-colorind'+(isMoz?'-ff':_ie)+(this.options.hideButton?' evo-hidden-button':''),
                        style='';
                    this._isPopup=true;
                    this._palette=null;
                    var v=e.val();
                    if(color!==null){
                        if(color != v) e.val(color).change();
                    }else if(v!==''){
                        color=this.options.color=v;
                    }
                    if(color===transColor){
                        css+=' evo-transparent';
                    }else{
                        style=(color!==null)?('background-color:'+color):'';
                    }
                    e.addClass('colorPicker '+this._id)
                        .wrap('<div style="width:'+(this.options.hideButton?this.element.width():this.element.width()+32)+'px;'+
                            (isIE?'margin-bottom:-21px;':'')+
                            (isMoz?'padding:1px 0;':'')+
                            '" class="evo-cp-wrap"></div>')
                        .after('<div class="'+css+'" style="'+style+'"></div>')
                        .on('keyup onpaste', function(evt){
                            var c=$(this).val();
                            if(c!=that.options.color){
                                that._setValue(c, true);
                            }
                        });
                    var showOn=this.options.showOn;
                    if(showOn==='both' || showOn==='focus'){
                        e.on('focus', function(){
                            that.showPalette();
                        });
                    }
                    if(showOn==='both' || showOn==='button'){
                        e.next().on('click', function(evt){
                            evt.stopPropagation();
                            that.showPalette();
                            return false;
                        });
                    }
                    break;
                default:
                    this._isPopup=false;
                    this._palette=this.element.html(this._paletteHTML())
                        .attr('aria-haspopup','true');
                    this._bindColors();
            }
            if(this.options.history){
                if(color){
                    this._add2History(color);
                }
                var c = this.options.initialHistory;
                if(c){
                    for (var i in c){
                        this._add2History(c[i]);
                    }
                }
            }
        },
    
        _paletteHTML: function() {
            var pIdx=this._paletteIdx=Math.abs(this._paletteIdx),
                opts=this.options,
                labels=opts.strings.split(',');
    
            var h='<div class="evo-pop'+_ie+' ui-widget ui-widget-content ui-corner-all"'+
                (this._isPopup?' style="position:absolute"':'')+'>'+
                // palette
                '<span>'+this['_paletteHTML'+pIdx]()+'</span>'+
                // links
                '<div class="evo-more"><a href="javascript:void(0)">'+labels[1+pIdx]+'</a>';
            if(opts.history){
                h+='<a href="javascript:void(0)" class="evo-hist">'+labels[5]+'</a>';
            }
            h+='</div>';
            // indicator
            if(opts.displayIndicator){
                h+=this._colorIndHTML(this.options.color)+this._colorIndHTML('');
            }
            h+='</div>';
            return h;
        },
    
        _colorIndHTML: function(c) {
            var css=isIE?'evo-colorbox-ie ':'',
                style='';
    
            if(c){
                if(c===transColor){
                    css+='evo-transparent';
                }else{
                    style='background-color:'+c;
                }
            }else{
                style='display:none';
            }
            return '<div class="evo-color" style="float:left">'+
                '<div style="'+style+'" class="'+css+'"></div><span>'+ // class="evo-colortxt-ie"
                (c?c:'')+'</span></div>';
        },
    
        _paletteHTML1: function() {
            var opts=this.options,
                labels=opts.strings.split(','),
                oTD='<td style="background-color:',
                cTD=isIE?'"><div style="width:2px;"></div></td>':'"><span></span></td>',
                oTRTH='<tr><th colspan="10" class="ui-widget-content">',
                i,
                css='evo-palette'+_ie + (opts.customTheme ? ' cust-theme':'');
    
            var h='<table class="'+css+'">'+oTRTH+labels[0]+'</th></tr><tr>';
    
            if (opts.customTheme) {
                for (i=0, ml=opts.customTheme.length;i<ml;i++) {
                    h+=oTD+opts.customTheme[i]+cTD;
                    if(i%10===9){
                        h+='</tr><tr>';
                    }
                }
            } else {
                oTD+='#';
                // base theme colors
                for(i=0;i<10;i++){ 
                    h+=oTD+baseThemeColors[i]+cTD;
                }
                h+='</tr>';
                if(!isIE){
                    h+='<tr><th colspan="10"></th></tr>';
                }
                h+='<tr class="top">';
                // theme colors
                for(i=0;i<10;i++){ 
                    h+=oTD+subThemeColors[i]+cTD;
                }
                for(var r=1;r<4;r++){
                    h+='</tr><tr class="in">';
                    for(i=0;i<10;i++){ 
                        h+=oTD+subThemeColors[r*10+i]+cTD;
                    }
                }
                h+='</tr><tr class="bottom">';
                for(i=40;i<50;i++){ 
                    h+=oTD+subThemeColors[i]+cTD;
                }
                h+='</tr>'+oTRTH;
                // transparent color
                if(opts.transparentColor){
                    h+='<div class="evo-transparent evo-tr-box"></div>';
                }
                h+=labels[1]+'</th></tr><tr>';
                // standard colors
                for(i=0;i<10;i++){ 
                    h+=oTD+standardColors[i]+cTD;
                }
            }
            h+='</tr></table>';
            return h; 
        },
    
        _paletteHTML2: function() {
            var i, iMax,
                oTD='<td style="background-color:#',
                cTD=isIE?'"><div style="width:5px;"></div></td>':'"><span></span></td>',
                oTableTR='<table class="evo-palette2'+_ie+'"><tr>',
                cTableTR='</tr></table>';
    
            var h='<div class="evo-palcenter">';
            // hexagon colors
            for(var r=0,rMax=webColors.length;r<rMax;r++){
                h+=oTableTR;
                var cs=webColors[r];
                for(i=0,iMax=cs.length;i<iMax;i++){ 
                    h+=oTD+cs[i]+cTD;
                }
                h+=cTableTR;
            }
            h+='<div class="evo-sep"></div>';
            // gray scale colors
            var h2='';
            h+=oTableTR;
            for(i=255;i>10;i-=10){
                h+=oTD+int2Hex3(i)+cTD;
                i-=10;
                h2+=oTD+int2Hex3(i)+cTD;
            }
            h+=cTableTR+oTableTR+h2+cTableTR+'</div>';
            return h;
        },
    
        _switchPalette: function(link) {
            if(this._enabled){
                var idx, 
                    content, 
                    label,
                    opts=this.options,
                    labels=opts.strings.split(',');
                if($(link).hasClass('evo-hist')){
                    // history
                    var h='<table class="evo-palette"><tr><th class="ui-widget-content">'+
                        labels[5]+'</th></tr></tr></table>'+
                        '<div class="evo-cHist">';
                    if(history.length===0){
                        h+='<p>&nbsp;'+labels[6]+'</p>';
                    }else{
                        for(var i=history.length-1;i>-1;i--){
                            if(history[i].length===9){
                                if(opts.transparentColor){
                                    h+='<div class="evo-transparent"></div>';
                                }
                            }else{
                                h+='<div style="background-color:'+history[i]+'"></div>';
                            }
                        }
                    }
                    h+='</div>';
                    idx=-this._paletteIdx;
                    content=h;
                    label=labels[4];
                }else{
                    // palette
                    if(this._paletteIdx<0){
                        idx=-this._paletteIdx;
                        this._palette.find('.evo-hist').show();
                    }else{
                        idx=(this._paletteIdx==2)?1:2;
                    }
                    content=this['_paletteHTML'+idx]();
                    label=labels[idx+1];
                    this._paletteIdx=idx;
                }
                this._paletteIdx=idx;
                var e=this._palette.find('.evo-more')
                    .prev().html(content).end()
                    .children().eq(0).html(label);
                if(idx<0){
                    e.next().hide();
                }
            }
        },
    
        _downOrUpPositioning: function() {
            var el = this.element,
                i = 0;
            while (el !== null && i < 100) {
                // Look up the first parent with non-visibile overflow and compute the relative position
                if (el.css('overflow') != 'visible') {
                    var bott = this._palette.offset().top + this._palette.height(),
                        pBott = el.offset().top + el.height(),
                        top = this._palette.offset().top - this._palette.height() - this.element.outerHeight(),
                        pTop = el.offset().top,
                        openUp = bott > pBott && top > pTop;
                    if (openUp) {
                        this._palette.css({ bottom: this.element.outerHeight()+'px' });
                    } else {
                        this._palette.css({ bottom: 'auto' });
                    }
                    break;
                }
                if (el[0].tagName == 'HTML') break;
                else el = el.offsetParent();
                i++;
            }
        },
    
        showPalette: function() {
            if(this._enabled){
                this._active=true;
                $('.colorPicker').not('.'+this._id).colorpicker('hidePalette');
                if(this._palette===null){
                    this._palette=this.element.next()
                        .after(this._paletteHTML()).next()
                        .on('click',function(evt){
                            evt.stopPropagation();
                            return false;
                        });
                    this._bindColors();
                    var that=this;
                    if(this._isPopup){
                        this._downOrUpPositioning();
                        $(document.body).on('click.'+that._id, function(evt){
                            if(evt.target!=that.element.get(0)){
                                that.hidePalette();
                            }
                        }).on('keyup.'+that._id, function(evt){
                            if(evt.keyCode===27){
                                that.hidePalette();
                            }
                        });
                    }
                }
            }
            return this;
        },
    
        hidePalette: function() {
            if(this._isPopup && this._palette){
                $(document.body).off('click.'+this._id);
                var that=this;
                this._palette.off('mouseover click', 'td,.evo-transparent')
                    .fadeOut(function(){
                        that._palette.remove();
                        that._palette=that._cTxt=null;
                    })
                    .find('.evo-more a').off('click');
            }
            return this;
        },
    
        _bindColors: function() {
            var that=this,
                opts=this.options,
                es=this._palette.find('div.evo-color'),
                sel=opts.history?'td,.evo-cHist>div':'td';
    
            if(opts.transparentColor){
                sel+=',.evo-transparent';
            }
            this._cTxt1=es.eq(0).children().eq(0);
            this._cTxt2=es.eq(1).children().eq(0);
            this._palette
                .on('click', sel, function(evt){
                    if(that._enabled){
                        var $this=$(this);
                        that._setValue($this.hasClass('evo-transparent')?transColor:toHex3($this.attr('style').substring(17)));
                        that._active=false;
                    }
                })
                .on('mouseover', sel, function(evt){
                    if(that._enabled){
                        var $this=$(this),
                            c=$this.hasClass('evo-transparent')?transColor:toHex3($this.attr('style').substring(17));
                        if(that.options.displayIndicator){
                            that._setColorInd(c,2);
                        }
                        if(that._active){
                            that.element.trigger('mouseover.color', c);
                        }
                    }
                })
                .find('.evo-more a').on('click', function(){
                    that._switchPalette(this);
                    return false; // otherwise IE10 will fire onbeforeunload event @see https://stackoverflow.com/questions/10548614/anchor-javascriptvoid0-causing-window-onbeforeunload-to-fire-on-ie
                });
        },
    
        val: function(value) {
            if (typeof value=='undefined') {
                return this.options.color;
            }else{
                this._setValue(value);
                return this;
            }
        },
    
        _setValue: function(c, noHide) {
            c = c.replace(/ /g,'');
            this.options.color=c;
            if(this._isPopup){
                if(!noHide){
                    this.hidePalette();
                }
                this._setBoxColor(this.element.val(c).change().next(), c);
            }else{
                this._setColorInd(c,1);
            }
            if(this.options.history && this._paletteIdx>0){
                this._add2History(c);
            }
            this.element.trigger('change.color', c);
        },
    
        _setColorInd: function(c, idx) {
            var $box=this['_cTxt'+idx];
            this._setBoxColor($box, c);
            $box.next().html(c);
        },
    
        _setBoxColor: function($box, c) {
            if(c===transColor){
                $box.addClass('evo-transparent')
                    .removeAttr('style');
            }else{
                $box.removeClass('evo-transparent')
                    .attr('style','background-color:'+c);
            }
        },
    
        _setOption: function(key, value) {
            if(key=='color'){
                this._setValue(value, true);
            }else{
                this.options[key]=value;
            }
        },
    
        _add2History: function(c) {
            var iMax=history.length;
            // skip color if already in history
            for(var i=0;i<iMax;i++){
                if(c==history[i]){
                    return;
                }
            }
            // limit of 28 colors in history
            if(iMax>27){
                history.shift();
            }
            // add to history
            history.push(c);
        },
    
        clear: function(){
            this.hidePalette().val('');
        },
    
        enable: function() {
            var e=this.element;
            if(this._isPopup){
                e.removeAttr('disabled');
            }else{
                e.css({
                    'opacity': '1', 
                    'pointer-events': 'auto'
                });
            }
            if(this.options.showOn!=='focus'){
                this.element.next().addClass('evo-pointer');
            }
            e.removeAttr('aria-disabled');
            this._enabled=true;
            return this;
        },
    
        disable: function() {
            var e=this.element;
            if(this._isPopup){
                e.attr('disabled', 'disabled');
            }else{
                this.hidePalette();
                e.css({
                    'opacity': '0.3', 
                    'pointer-events': 'none'
                });
            }
            if(this.options.showOn!=='focus'){
                this.element.next().removeClass('evo-pointer');
            }
            e.attr('aria-disabled','true');
            this._enabled=false;
            return this;
        },
    
        isDisabled: function() {
            return !this._enabled;
        },
    
        destroy: function() {
            $(document.body).off('click.'+this._id);
            if(this._palette){
                this._palette.off('mouseover click', 'td,.evo-cHist>div,.evo-transparent')
                    .find('.evo-more a').off('click');
                if(this._isPopup){
                    this._palette.remove();
                }
                this._palette=this._cTxt=null;
            }
            if(this._isPopup){
                this.element
                    .next().off('click').remove()
                    .end().off('focus').unwrap();
            }
            this.element.removeClass('colorPicker '+this.id).empty();
            $.Widget.prototype.destroy.call(this);
        }
    
    });
    
    })(jQuery);